Micron Document
baubs git

Node / mirrors / respira / commits / 20e9fa1

Commit 20e9fa13e7980012cd36d527508489cb6da2d9a7


Parents : e49a63a
Author : Jan-Henrik Bruhn <jan-henrik.bruhn@offis.de>
Date : 2025-12-27T17:39:26+01:00

refactor: Remove cross-store dependencies using Zustand event store

Replace direct store imports and calls with a Zustand-based event system
for decoupled cross-store communication.

Changes:
- Created storeEvents.ts using Zustand for event management
- Removed direct usePatternStore import from useMachineStore
- Removed dynamic imports for useMachineUploadStore and useMachineCacheStore
- Added event subscriptions in usePatternStore, useMachineUploadStore, and useMachineCacheStore
- useMachineStore now emits patternDeleted event instead of calling other stores directly

Benefits:
- Stores can be tested in isolation
- No tight coupling between stores
- Clear, explicit event-driven data flow
- Uses Zustand's built-in subscription system
- Easier to refactor stores independently

Fixes #37

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Changes
Diff

diff --git a/src/stores/storeEvents.ts b/src/stores/storeEvents.ts
new file mode 100644
index 0000000..f4d93a2
--- /dev/null
+++ b/src/stores/storeEvents.ts
@@ -0,0 +1,44 @@
+/**
+ * Store Events
+ *
+ * Zustand-based event store for cross-store communication without tight coupling.
+ * Uses Zustand's built-in subscription system to emit and react to events.
+ */
+
+import { create } from "zustand";
+
+interface EventState {
+ // Event counters - incrementing these triggers subscriptions
+ patternDeletedCount: number;
+
+ // Actions to emit events
+ emitPatternDeleted: () => void;
+}
+
+/**
+ * Event store using Zustand for cross-store communication.
+ * Stores can emit events by calling actions, and subscribe to events using Zustand's subscribe.
+ */
+export const useEventStore = create<EventState>((set) => ({
+ patternDeletedCount: 0,
+
+ emitPatternDeleted: () => {
+ set((state) => ({ patternDeletedCount: state.patternDeletedCount + 1 }));
+ },
+}));
+
+/**
+ * Subscribe to pattern deleted event
+ * @param callback - Function to call when event is emitted
+ * @returns Unsubscribe function
+ */
+export const onPatternDeleted = (callback: () => void): (() => void) => {
+ let prevCount = useEventStore.getState().patternDeletedCount;
+
+ return useEventStore.subscribe((state) => {
+ if (state.patternDeletedCount !== prevCount) {
+ prevCount = state.patternDeletedCount;
+ callback();
+ }
+ });
+};

diff --git a/src/stores/useMachineCacheStore.ts b/src/stores/useMachineCacheStore.ts
index f13899d..5023a2e 100644
--- a/src/stores/useMachineCacheStore.ts
+++ b/src/stores/useMachineCacheStore.ts
@@ -1,6 +1,7 @@
import { create } from "zustand";
import type { PesPatternData } from "../formats/import/pesImporter";
import { uuidToString } from "../services/PatternCacheService";
+import { onPatternDeleted } from "./storeEvents";
/**
* Machine Cache Store
@@ -192,3 +193,8 @@ export const useMachineCacheStore = create<MachineCacheState>((set, get) => ({
});
},
}));
+
+// Subscribe to pattern deleted event
+onPatternDeleted(() => {
+ useMachineCacheStore.getState().clearResumeState();
+});

diff --git a/src/stores/useMachineStore.ts b/src/stores/useMachineStore.ts
index 7ee6c57..b0c35db 100644
--- a/src/stores/useMachineStore.ts
+++ b/src/stores/useMachineStore.ts
@@ -13,7 +13,7 @@ import { SewingMachineError } from "../utils/errorCodeHelpers";
import { uuidToString } from "../services/PatternCacheService";
import { createStorageService } from "../platform";
import type { IStorageService } from "../platform/interfaces/IStorageService";
-import { usePatternStore } from "./usePatternStore";
+import { useEventStore } from "./storeEvents";
interface MachineState {
// Service instances
@@ -291,16 +291,8 @@ export const useMachineStore = create<MachineState>((set, get) => ({
sewingProgress: null,
});
- // Clear uploaded pattern data in pattern store
- usePatternStore.getState().clearUploadedPattern();
-
- // Clear upload state in upload store
- const { useMachineUploadStore } = await import("./useMachineUploadStore");
- useMachineUploadStore.getState().reset();
-
- // Clear resume state in cache store
- const { useMachineCacheStore } = await import("./useMachineCacheStore");
- useMachineCacheStore.getState().clearResumeState();
+ // Emit pattern deleted event for other stores to react
+ useEventStore.getState().emitPatternDeleted();
await refreshStatus();
} catch (err) {

diff --git a/src/stores/useMachineUploadStore.ts b/src/stores/useMachineUploadStore.ts
index ce4ac3a..621200c 100644
--- a/src/stores/useMachineUploadStore.ts
+++ b/src/stores/useMachineUploadStore.ts
@@ -1,6 +1,7 @@
import { create } from "zustand";
import type { PesPatternData } from "../formats/import/pesImporter";
import { uuidToString } from "../services/PatternCacheService";
+import { onPatternDeleted } from "./storeEvents";
/**
* Machine Upload Store
@@ -126,3 +127,8 @@ export const useMachineUploadStore = create<MachineUploadState>((set) => ({
set({ uploadProgress: 0, isUploading: false });
},
}));
+
+// Subscribe to pattern deleted event
+onPatternDeleted(() => {
+ useMachineUploadStore.getState().reset();
+});

diff --git a/src/stores/usePatternStore.ts b/src/stores/usePatternStore.ts
index 94f568b..a05297b 100644
--- a/src/stores/usePatternStore.ts
+++ b/src/stores/usePatternStore.ts
@@ -1,5 +1,6 @@
import { create } from "zustand";
import type { PesPatternData } from "../formats/import/pesImporter";
+import { onPatternDeleted } from "./storeEvents";
interface PatternState {
// Original pattern (pre-upload)
@@ -121,3 +122,8 @@ export const useUploadedPatternOffset = () =>
usePatternStore((state) => state.uploadedPatternOffset);
export const usePatternRotation = () =>
usePatternStore((state) => state.patternRotation);
+
+// Subscribe to pattern deleted event
+onPatternDeleted(() => {
+ usePatternStore.getState().clearUploadedPattern();
+});

Served by rngit 1.3.3 - Generated in 0.08s